package com.joysuch.wwyt.core.service.impl;

import cn.zlg.common.util.CollectionUtils;
import com.joysuch.wwyt.bp.bean.BpDeviceFacilityCheckRecordBean;
import com.joysuch.wwyt.bp.bean.facility.BpProductionFacilityListBean;
import com.joysuch.wwyt.bp.bean.facility.BpProductionFacilityTypeDto;
import com.joysuch.wwyt.bp.entity.BpDeviceFacilityCheckRecord;
import com.joysuch.wwyt.bp.entity.dsl.QBpDeviceFacilityCheckRecord;
import com.joysuch.wwyt.bp.repository.BpDepartDao;
import com.joysuch.wwyt.bp.repository.BpDeviceFacilityCheckRecordDao;
import com.joysuch.wwyt.bp.service.BpProductionFacilityService;
import com.joysuch.wwyt.bp.service.BpProductionFacilityTypeService;
import com.joysuch.wwyt.common.entity.CommonIndexNotify;
import com.joysuch.wwyt.common.enums.CommonIndexNotifyTypes;
import com.joysuch.wwyt.common.service.CommonIndexNotifyService;
import com.joysuch.wwyt.core.common.util.DateTimeUtil;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BpDeviceFacilityCheckRecordService;
import com.joysuch.wwyt.util.StringUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import org.omg.CORBA.Current;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@Service
public class BpDeviceFacilityCheckRecordServiceImpl implements BpDeviceFacilityCheckRecordService {

    @Autowired
    private BpDeviceFacilityCheckRecordDao bpDeviceFacilityCheckRecordDao;
    @Autowired
    private BpDepartDao bpDepartDao;
    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private BpProductionFacilityService bpProductionFacilityService;
    @Autowired
    private BpProductionFacilityTypeService bpProductionFacilityTypeService;
    @Autowired
    private CommonIndexNotifyService commonIndexNotifyService;

    /**
     * 保存
     *
     * @param bean
     * @return
     */
    @Override
    public BpDeviceFacilityCheckRecord save(BpDeviceFacilityCheckRecordBean bean) {
        BpDeviceFacilityCheckRecord record = new BpDeviceFacilityCheckRecord();
        if (bean.getId() != null) {
            record = bpDeviceFacilityCheckRecordDao.findById(bean.getId()).get();
        }
        BeanUtils.copyProperties(bean, record);
        if (bean.getCheckTime() == null) {
            record.setCheckTime(new Date());
        }
        BpDeviceFacilityCheckRecord save = bpDeviceFacilityCheckRecordDao.save(record);
        //保存后查看当前设备的类型是否设置了到期提醒，如果有则新增到期提醒记录
        BpProductionFacilityListBean productionFacility = bpProductionFacilityService.findById(save.getDeviceFacilityId());
        if (productionFacility != null && productionFacility.getType() != null && productionFacility.getInspectionDays() != null/* && save.getCheckValidityDate().getTime() > System.currentTimeMillis()*/) {
            BpProductionFacilityTypeDto dto = bpProductionFacilityTypeService.getById(productionFacility.getType());
            if (dto != null) {
                if (dto.getExpireRemindOrNot() != null && dto.getExpireRemindOrNot() == 1) {
                    LocalDateTime localDateTime = DateTimeUtil.date2LocalDateTime(save.getCheckValidityDate()).minusDays(Integer.valueOf(dto.getRemindType()));
                    Date date = DateTimeUtil.localDateTime2Date(localDateTime);
                    //如果此次填写的信息需要未来或者今天提醒，并且此记录不是最新的记录则无需新增到期提醒记录
                    if (!date.before(new Date()) && !isLastRecord(save)){
                        return save;
                    }
                    //如果是提醒未来的消息并且是最新的记录则去除未来还未发出的通知
                    if (date.after(new Date())){
                        bpProductionFacilityService.removeRemindNotify(productionFacility.getId(), CommonIndexNotifyTypes.PRODUCTION_FACILITY_CHECK.getType());
                    }
                    bpProductionFacilityService.remindNotify(productionFacility.getName(), productionFacility.getId(), save.getId(), productionFacility.getType(), date, save.getCheckValidityDate(), CommonIndexNotifyTypes.PRODUCTION_FACILITY_CHECK.getType(), "设备检查");
                }
            }
        }
        return save;
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public BpDeviceFacilityCheckRecordBean getById(Long id) {
        BpDeviceFacilityCheckRecord record = bpDeviceFacilityCheckRecordDao.findById(id).orElseThrow(() -> new IllegalArgumentException("检查记录不存在"));
        return record2Bean(record);
    }

    /**
     * 分页
     *
     * @param page
     * @return
     */
    @Override
    public Page<BpDeviceFacilityCheckRecordBean> page(Pageable page, Long deviceFacilityId) {
        QBpDeviceFacilityCheckRecord q = QBpDeviceFacilityCheckRecord.BpDeviceFacilityCheckRecord;
        Predicate predicate = null;
        if (deviceFacilityId != null) {
            predicate = ExpressionUtils.and(predicate, q.deviceFacilityId.eq(deviceFacilityId));
        }

        Page<BpDeviceFacilityCheckRecord> all = predicate == null ? bpDeviceFacilityCheckRecordDao.findAll(page) : bpDeviceFacilityCheckRecordDao.findAll(predicate, page);
        return PageDataUtils.convertPageData(all, new PageDataUtils.PageDataConvert<BpDeviceFacilityCheckRecordBean, BpDeviceFacilityCheckRecord>() {
            @Override
            public BpDeviceFacilityCheckRecordBean convert(BpDeviceFacilityCheckRecord record) {
                return record2Bean(record);
            }
        });
    }

    /**
     * 删除
     *
     * @param recordId
     */
    @Override
    public void deleteById(Long recordId) {
        bpDeviceFacilityCheckRecordDao.deleteById(recordId);
        //该条记录所绑定的到期提醒也要删掉
        List<CommonIndexNotify> list = commonIndexNotifyService.getByTypeAndRecordId(CommonIndexNotifyTypes.PRODUCTION_FACILITY_CHECK.getType(), recordId);
        if (CollectionUtils.isNotEmpty(list)) {
            for (CommonIndexNotify notify : list) {
                if (notify != null && notify.getRemindedOrNot() == 0) {
                    commonIndexNotifyService.cancelAndRemove(notify);
                    commonIndexNotifyService.delete(notify.getId());
                }
            }
        }
    }

    private BpDeviceFacilityCheckRecordBean record2Bean(BpDeviceFacilityCheckRecord record) {
        BpDeviceFacilityCheckRecordBean bean = new BpDeviceFacilityCheckRecordBean();
        if (record != null) {
            BeanUtils.copyProperties(record, bean);
            bean.setCheckDepartName(getDepartName(record.getCheckDepartId()));
            bean.setChiefDepartName(getDepartName(record.getChiefDepartId()));
            bean.setCheckPersonName(getUserName(record.getCheckPersonId()));
        }
        return bean;
    }

    private String getDepartName(Long id) {
        String name = null;
        if (id != null) {
            name = bpDepartDao.getNameById(id);
        }
        return name;
    }

    private String getUserName(Long id) {
        String name = null;
        if (id != null) {
            name = baseUserDao.getRealNameById(id);
        }
        return name;
    }

    /**
     * 判断此条检查记录是否是该设备最新的记录
     * @param save
     * @return
     */
    private boolean isLastRecord(BpDeviceFacilityCheckRecord save){
        Long id = save.getId();
        Long deviceFacilityId = save.getDeviceFacilityId();
        Date detectDate = save.getCheckValidityDate();
        Long lastRecord = bpDeviceFacilityCheckRecordDao.isLastRecord(id, deviceFacilityId, detectDate);
        return lastRecord == 0;
    }
}
